package manager.auth.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import common.SnowflakeIdWorker;
import manager.auth.dao.*;
import manager.auth.service.UserPermissionService;
import manager.auth.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static manager.config.AuthInteceptor.getAdminUserInfo;

@Service(value = "userPermissionService")
public class UserPermissionServiceImpl implements UserPermissionService {
    @Autowired
    private SysPermissionDao sysPermissionDao;
    @Autowired
    private SysRoleDao sysRoleDao;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private SysRolePermissionDao sysRolePermissionDao;

    /**
     * 用户分页查询
     *
     * @param sysUserConditionVO
     * @return
     */
    @Override
    public PageInfo<SysUserVO> selectPageUser(SysUserConditionVO sysUserConditionVO) {
        Example example = new Example(SysUserVO.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(sysUserConditionVO.getUsername())) {
            criteria.andEqualTo("username", sysUserConditionVO.getUsername());
        }
        PageHelper.startPage(sysUserConditionVO.getPageInfo().getPageNum(), sysUserConditionVO.getPageInfo().getPageSize());
        List<SysUserVO> userList = sysUserDao.selectByExample(example);
        PageInfo<SysUserVO> pageInfo = new PageInfo<>(userList);
        return pageInfo;
    }

    /**
     * 角色分页查询
     *
     * @param sysRoleConditionVO
     * @return
     */
    @Override
    public PageInfo<SysRoleVO> selectPageRole(SysRoleConditionVO sysRoleConditionVO) {
        Example example = new Example(SysRoleVO.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(sysRoleConditionVO.getName())) {
            criteria.andEqualTo("name", sysRoleConditionVO.getName());
        }
        criteria.andEqualTo("roleType", sysRoleConditionVO.getRoleType());
        PageHelper.startPage(sysRoleConditionVO.getPageInfo().getPageNum(), sysRoleConditionVO.getPageInfo().getPageSize());
        List<SysRoleVO> roleList = sysRoleDao.selectByExample(example);
        PageInfo<SysRoleVO> pageInfo = new PageInfo<>(roleList);
        return pageInfo;
    }

    /**
     * @param sysPermissionConditionVO
     * @return
     */
    @Override
    public List<SysPermissionVO> selectPagePermission(SysPermissionConditionVO sysPermissionConditionVO) {
        Example example = new Example(SysPermissionVO.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(sysPermissionConditionVO.getName())) {
            criteria.andEqualTo("name", sysPermissionConditionVO.getName());
        }
        if (StringUtils.isNotBlank(sysPermissionConditionVO.getParentId())) {
            criteria.andEqualTo("parentId", sysPermissionConditionVO.getParentId());
        }
        criteria.andEqualTo("type", sysPermissionConditionVO.getType());
        //分页查询以及分类
        int permissionCount = sysPermissionDao.selectCountByExample(example);
        List<SysPermissionVO> list = batchSearchPermission(sysPermissionConditionVO, permissionCount);
        return list;
    }

    /**
     * 并行查询所有的权限数据
     *
     * @return
     */
    private List<SysPermissionVO> batchSearchPermission(SysPermissionConditionVO sysPermissionConditionVO, int permissionCount) {
        List<SysPermissionVO> result = new ArrayList<>();
        int pageCount = permissionCount / 1000 + 1;
        List<Integer> pageCountList = new ArrayList<>();
        for (int i = 1; i <= pageCount; i++) {
            pageCountList.add(i);
        }
        pageCountList.parallelStream().forEach(l -> {
            result.addAll(getSysPermissionOnePage(sysPermissionConditionVO, l));
        });
        return result;
    }

    private List<SysPermissionVO> getSysPermissionOnePage(SysPermissionConditionVO sysPermissionConditionVO, int currentPage) {
        List<SysPermissionVO> result = new ArrayList<>();
        Example example = new Example(SysPermissionVO.class);
        Example.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(sysPermissionConditionVO.getName())) {
            criteria.andEqualTo("name", sysPermissionConditionVO.getName());
        }
        if (StringUtils.isNotBlank(sysPermissionConditionVO.getParentId())) {
            criteria.andEqualTo("parentId", sysPermissionConditionVO.getParentId());
        }
        criteria.andEqualTo("type", sysPermissionConditionVO.getType());
        PageHelper.startPage(currentPage, 1000);
        List<SysPermissionVO> permissionList = sysPermissionDao.selectByExample(example);
        PageInfo<SysPermissionVO> pageInfo = new PageInfo<>(permissionList);
        result.addAll(pageInfo.getList());
        return result;
    }

    /**
     * 根据条件查询用户
     *
     * @param sysUserVO
     * @return
     */
    @Override
    public List<SysUserVO> selectUser(SysUserVO sysUserVO) {
        return sysUserDao.select(sysUserVO);
    }

    /**
     * 根据条件查询角色
     *
     * @param sysRoleVO
     * @return
     */
    @Override
    public List<SysRoleVO> selectRole(SysRoleVO sysRoleVO) {
        return sysRoleDao.select(sysRoleVO);
    }

    /**
     * 根据条件查询权限
     *
     * @param sysPermissionVO
     * @return
     */
    @Override
    public List<SysPermissionVO> selectPermission(SysPermissionVO sysPermissionVO) {
        return sysPermissionDao.select(sysPermissionVO);
    }

    /**
     * 添加用户
     *
     * @param sysUserVO
     */
    @Override
    public void addUser(SysUserVO sysUserVO) {
        sysUserVO.setId(String.valueOf(SnowflakeIdWorker.nextId()));
        String salt = BCrypt.gensalt();
        String currentPass = BCrypt.hashpw(sysUserVO.getPassword(), salt);
        sysUserVO.setPassword(currentPass);
        sysUserVO.setSalt(salt);
        sysUserDao.insert(sysUserVO);
    }

    /**
     * 修改用户
     *
     * @param sysUserVO
     */
    @Override
    public void updateUser(SysUserVO sysUserVO) {
        UserInfo userInfo=getAdminUserInfo();
        if(StringUtils.isNotBlank(sysUserVO.getPassword())){
            String salt = BCrypt.gensalt();
            String currentPass = BCrypt.hashpw(sysUserVO.getPassword(), salt);
            sysUserVO.setPassword(currentPass);
            sysUserVO.setSalt(salt);
        }
        if(StringUtils.isBlank(sysUserVO.getPassword())){
            String salt = BCrypt.gensalt();
            String currentPass = BCrypt.hashpw("8ddcff3a80f4189ca1c9d4d902c3c909", salt);
            sysUserVO.setPassword(currentPass);
            sysUserVO.setSalt(salt);
        }
        Example example = new Example(SysUserVO.class);
        Example.Criteria criteria = example.createCriteria();
        if(StringUtils.isNotBlank(sysUserVO.getUsername())){
            criteria.andEqualTo("username", sysUserVO.getUsername());
        }else{
            criteria.andEqualTo("username", userInfo.getUsername());
        }
        SysUserVO userVO=new SysUserVO();
        userVO.setSalt(sysUserVO.getSalt());
        userVO.setPassword(sysUserVO.getPassword());
        userVO.setPhone(sysUserVO.getPhone());
        sysUserDao.updateByExampleSelective(sysUserVO, example);
    }

    /**
     * 批量删除用户
     *
     * @param sysUserList
     */
    @Override
    public void deleteUser(List<SysUserVO> sysUserList) {
        Example example = new Example(SysUserVO.class);
        Example.Criteria criteria = example.createCriteria();
        List<String> deleteIds = sysUserList.stream().map(SysUserVO::getId).collect(Collectors.toList());
        criteria.andIn("id", deleteIds);
        sysUserDao.deleteByExample(example);
    }

    /**
     * 添加角色
     *
     * @param sysRoleVO
     */
    @Override
    public void addRole(SysRoleVO sysRoleVO) {
        sysRoleVO.setId(String.valueOf(SnowflakeIdWorker.nextId()));
        sysRoleDao.insert(sysRoleVO);
    }

    @Override
    public void updateRole(SysRoleVO sysUserVO) {
        Example example = new Example(SysUserVO.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", sysUserVO.getId());
        sysRoleDao.updateByExample(sysUserVO,example);
    }

    @Override
    public void deleteRole(List<SysRoleVO> sysRoleList) {
        Example example = new Example(SysUserVO.class);
        Example.Criteria criteria = example.createCriteria();
        List<String> deleteIds = sysRoleList.stream().map(SysRoleVO::getId).collect(Collectors.toList());
        criteria.andIn("id", deleteIds);
        sysRoleDao.deleteByExample(example);
    }

    @Override
    public void addPermission(SysPermissionVO sysPermissionVO) {
        sysPermissionVO.setId(String.valueOf(SnowflakeIdWorker.nextId()));
        sysPermissionDao.insert(sysPermissionVO);
    }

    @Override
    public void updatePermission(SysPermissionVO sysPermissionVO) {
        Example example = new Example(SysUserVO.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", sysPermissionVO.getId());
        sysPermissionDao.updateByExampleSelective(sysPermissionVO, example);
    }

    @Override
    public void deletePermission(List<SysPermissionVO> sysPermissionList) {
        Example example = new Example(SysPermissionVO.class);
        Example.Criteria criteria = example.createCriteria();
        List<String> permissionIds = sysPermissionList.stream().map(SysPermissionVO::getId).collect(Collectors.toList());
        criteria.andIn("id", permissionIds);
        sysPermissionDao.deleteByExample(example);
    }

    @Override
    public void addUserRoleRls(List<SysUserRoleVO> sysUserVOList) {
        sysUserRoleDao.insertList(sysUserVOList);
    }

    @Override
    public void addRolePermissionRls(List<SysRolePermissionVO> sysRolePermissionVOList) {
        sysRolePermissionDao.insertList(sysRolePermissionVOList);
    }

    @Override
    public List<SysUserRoleVO> getUserRoleRls(SysUserRoleVO sysUserRoleVO) {
        return sysUserRoleDao.select(sysUserRoleVO);
    }

    @Override
    public List<SysPermissionVO> getRolePermissionRls(SysRolePermissionVO sysRolePermissionVO) {
        List<SysRolePermissionVO> rolePermissionList=sysRolePermissionDao.select(sysRolePermissionVO);
        List<String> permissionIdList=rolePermissionList.stream().map(item->item.getPermissionId()).collect(Collectors.toList());
        Example example=new Example(SysPermissionVO.class);
        example.createCriteria().andIn("id",permissionIdList);
        return sysPermissionDao.selectByExample(example);
    }

    @Override
    public void deleteRolePermissionRls(SysRolePermissionVO sysRolePermissionVO) {
        Example example = new Example(SysRolePermissionVO.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleId",sysRolePermissionVO.getRoleId());
        sysRolePermissionDao.deleteByExample(example);
    }

    @Override
    public void deleteUserRoleRls(SysUserRoleVO sysUserRoleVO) {
        Example example = new Example(SysUserRoleVO.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",sysUserRoleVO.getUserId());
        sysUserRoleDao.deleteByExample(example);
    }

    @Override
    public List<SysPermissionVO> getPermissionByUserId() {
        UserInfo userInfo=getAdminUserInfo();
        SysUserRoleVO sysUserRoleVO=new SysUserRoleVO();
        sysUserRoleVO.setUserId(String.valueOf(userInfo.getId()));
        List<SysUserRoleVO> userRoleList=sysUserRoleDao.select(sysUserRoleVO);
        Example rolePermissionExample = new Example(SysRolePermissionVO.class);
        List<String> roleIdList=userRoleList.stream().map(item->item.getRoleId()).collect(Collectors.toList());

        rolePermissionExample.createCriteria().andIn("roleId",roleIdList);
        List<SysRolePermissionVO> sysRolePermissionList=sysRolePermissionDao.selectByExample(rolePermissionExample);
        //获取所有的权限
        List<String> permissionIdList=sysRolePermissionList.stream().map(item->item.getPermissionId()).collect(Collectors.toList());

        Example permissionExample = new Example(SysPermissionVO.class);
        permissionExample.createCriteria().andIn("id",permissionIdList);
        List<SysPermissionVO> permissionList= sysPermissionDao.selectByExample(permissionExample);
        return permissionList;
    }

    /**
     * 初始化密码
     * @param sysUserVO
     */
    @Override
    public void initPassword(SysUserVO sysUserVO) {
        String salt = BCrypt.gensalt();
        String currentPass = BCrypt.hashpw("8ddcff3a80f4189ca1c9d4d902c3c909", salt);
        sysUserVO.setPassword(currentPass);
        sysUserVO.setSalt(salt);
        Example example = new Example(SysUserVO.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("username", sysUserVO.getUsername());
        sysUserDao.updateByExampleSelective(sysUserVO, example);
    }
}
